/*
 * Copyright (C) 2018 Logos Technology Ltd.
 */

package com.logos.common.source.network.request;

import com.logos.tool.log.LogUtil;

import java.io.IOException;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.Buffer;
import okio.BufferedSink;
import okio.ForwardingSink;
import okio.Okio;
import okio.Sink;

/**
 * @author Young Ken
 */

public class UploadFileRequestBody extends RequestBody {

    //实际起作用的RequestBody
    private RequestBody mRequestBody;
    //进度回调接口
    private final UploadFileProcessManager mManager;
    private CountingSink mCountingSink;
    private long mContentLength = -1;
    private String mFileName;

    public UploadFileRequestBody(String fileName, RequestBody requestBody,
                                 UploadFileProcessManager manager) {
        mFileName = fileName;
        mRequestBody = requestBody;
        mManager = manager;
        LogUtil.info("UploadFileRequestBody", "UploadFileRequestBody  UploadFileRequestBody");
    }

    @Override
    public MediaType contentType() {
        return mRequestBody.contentType();
    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
        mCountingSink = new CountingSink(sink);
        //将CountingSink转化为BufferedSink供writeTo()使用
        BufferedSink bufferedSink = Okio.buffer(mCountingSink);
        mRequestBody.writeTo(bufferedSink);
        bufferedSink.flush();
    }

    protected final class CountingSink extends ForwardingSink {
        private long mByteWritten;

        public CountingSink(Sink delegate) {
            super(delegate);
        }

        /**
         * 上传时调用该方法,在其中调用回调函数将上传进度暴露出去,该方法提供了缓冲区的自己大小
         *
         * @param source    source
         * @param byteCount byte
         * @throws IOException exception
         */
        @Override
        public void write(Buffer source, long byteCount) throws IOException {
            super.write(source, byteCount);
            mByteWritten += byteCount;
            mManager.updateSingleProcess(mFileName, byteCount, mByteWritten, contentLength());
        }
    }

    /**
     * 返回文件总的字节大小
     * 如果文件大小获取失败则返回-1
     *
     * @return long
     */
    @Override
    public long contentLength() {
        try {
            if (mContentLength == -1) {
                mContentLength = mRequestBody.contentLength();
                return mContentLength;
            }
            return mContentLength;
        } catch (IOException exception) {
            return mContentLength;
        }
    }

}

